import { getCardData, getTimorHolidayInfo } from '../service/phone.service.ts'
import { PhotoRespError, TodayHolidayError } from '../constant/err.type.ts'
import { sendMail } from '../config/nodemailer.ts'
import type { Context } from 'koa'
import { PhoneCardInfo, PhoneStatus } from '../interface/phone.interface.ts'
import moment from 'moment'

const statusInfo: PhoneStatus = {
  statusCode: 0,
  threshold: 1000,
}

let count: number = 0

class PhoneController {
  // 获取手机卡流量信息
  async getPhoneCardData(ctx: Context) {
    const { card } = ctx.request.body
    try {
      const res = await getCardData(card)
      let html: string = ''
      let respMsg: string = ''
      if (res.statusCode === 3) {
        // 已停用
        html = `<p>状态: <span style='color: red'>${res.status}</span></p>`
        respMsg = `状态: ${res.status}`
      } else {
        const G: number = res.residualFlow / 1024
        const data: string = G.toFixed(2)
        html = `<p>剩余: <span style='color: red'>${data} G</span>  总流量: ${res.package}  状态: ${res.status}</p>`
        respMsg = `剩余: ${data} G  总流量: ${res.package}  状态: ${res.status}`
      }
      const options = {
        to: process.env.APP_SEEYOU_EMAIL!,
        subject: '【物联卡】',
        html,
      }
      await sendMail(options)
      ctx.echo({ msg: respMsg })
    } catch (error) {
      PhotoRespError.error = ctx.seqErr(error)
      return ctx.app.emit('error', PhotoRespError, ctx)
    }
  }

  // 自动获取物联卡流量信息
  private async getAutoPhoneCardData() {
    const card: string = process.env.APP_CARD_NUMBER!
    try {
      const res: PhoneCardInfo = await getCardData(card)
      const options = {
        subject: '【物联卡】',
        html: '',
      }
      if (res.statusCode === 3) {
        // 已停用
        options.html = `<p>状态: <span style='color: red'>${res.status}</span></p>`
        // 停用状态只发送一次邮件
        if (statusInfo.statusCode !== 3) {
          await sendMail(options)
          // 重置剩余阀值，以便从停用状态变成正常状态时发送一次邮件
          statusInfo.threshold = 1000
        }
      } else {
        const G: number = res.residualFlow / 1024
        const data: string = G.toFixed(2)
        options.html = `<p>剩余: <span style='color: red'>${data} G</span>  总流量: ${res.package}  状态: ${res.status}</p>`
        // 流量低于阈值
        if (Math.floor(G) < statusInfo.threshold) await sendMail(options)
        statusInfo.threshold = Math.floor(G)
      }
      statusInfo.statusCode = res.statusCode
    } catch (error) {
      console.error(error)
    }
  }

  // 启动自动查询手机卡流量信息任务
  startAutoTask() {
    console.log(`查询物联卡流量自动任务执行中……`)
    // 10 分钟检查一次
    setInterval(
      async () => {
        count++
        console.log(
          `[ ${moment().format(
            'YYYY-MM-DD HH:mm:ss SSS',
          )} ] 物联卡流量：第 ${count} 次检查`,
        )
        await this.getAutoPhoneCardData()
      },
      1000 * 60 * 10,
    )
  }

  // 获取当天的节假日信息
  async getTodayHolidayInfo(ctx: Context) {
    try {
      const date = moment().format('YYYY-MM-DD')
      const res = await getTimorHolidayInfo(date)
      // {
      //   "code": 0,              // 0服务正常。-1服务出错
      //   "type": {
      //     "type": enum(0, 1, 2, 3), // 节假日类型，分别表示 工作日、周末、节日、调休。
      //     "name": "周六",         // 节假日类型中文名，可能值为 周一 至 周日、假期的名字、某某调休。
      //     "week": enum(1 - 7)    // 一周中的第几天。值为 1 - 7，分别表示 周一 至 周日。
      //   },
      //   "holiday": {
      //     "holiday": false,     // true表示是节假日，false表示是调休
      //     "name": "国庆前调休",  // 节假日的中文名。如果是调休，则是调休的中文名，例如'国庆前调休'
      //     "wage": 1,            // 薪资倍数，1表示是1倍工资
      //     "after": false,       // 只在调休下有该字段。true表示放完假后调休，false表示先调休再放假
      //     "target": '国庆节'     // 只在调休下有该字段。表示调休的节假日
      //   }
      // }
      const data = {
        date,
        info: '',
        workday: 1, // 1 工作日，0 非工作日
      }
      const { type, code } = res
      if (code === 0) {
        switch (type.type) {
          case 0:
          case 3:
            Object.assign(data, {
              info: `今天是${type.name}，要上班哦！`,
              workday: 1,
            })
            break
          case 1:
            Object.assign(data, {
              info: `${type.name}了，好好休息吧！`,
              workday: 0,
            })
            break
          case 2:
            Object.assign(data, {
              info: `${type.name}到了，出去浪吧！`,
              workday: 0,
            })
            break
        }
      }
      ctx.echo({ data })
    } catch (error) {
      TodayHolidayError.error = error
      return ctx.app.emit('error', TodayHolidayError, ctx)
    }
  }
}

const phoneController = new PhoneController()
// phoneController.startAutoTask()
export const { getPhoneCardData, getTodayHolidayInfo } = phoneController
export default phoneController
